/****************************************************************
 * Homework 5 'Scheduler' class implementation file
 * Author: Duncan Buell
 * Date last modified: 3 January 2010
 *
 * This class manages a priority queue of process blocks for
 * simulating process management in an operating system.
 * 
 * There are really only two nontrivial functions in this
 * class, one to add a process to the queue and one to dump
 * the entire queue into a string for debug printing.
 *
 * The other functions are simply pass-through functions for 
 * the 'empty', 'pop', and 'top' functions of the STL 
 * 'priority_queue' construct that is the main data object of
 * this class.
**/
#include "Scheduler.h"

static const char TAG[] = "Scheduler: ";

/****************************************************************
 * Constructor.
**/
Scheduler::Scheduler()
{
}

/****************************************************************
 * Destructor.
**/
Scheduler::~Scheduler()
{
}


/*******************************************************************************
 * Function to add a create a process using the given parameters and add
 * it to the priority queue.
 * Author: Andrew Shore
 * Date Last Modified: 23 March 2010
 *
 * This function creates a new process, sets the class variables of that
 * process by passing the parameters to the mutator functions and then uses
 * the STL priority queue function push() to add it to the queue. Information  
 * on the process being added is displayed to standard output. No error 
 * checking is done in this function, the parameters are assumed to be 
 * correct when passed in by the main function.

 * Parameters:
 *   long pid - used to set process id
 *   long startTime - used to set start time
 *   long execTime - used to set execution time
 *
 * Output: the information of the process being added
 *
 * Returns: none
*******************************************************************************/
void Scheduler::addProcess(long pid, long startTime, long execTime){
  Process newProcess;
  newProcess.setPid(pid);
  newProcess.setStartTime(startTime);
  newProcess.setExecTime(execTime);

  theSchedule.push(newProcess);
  cout << TAG << " create process id, start, exec, finish " << pid << " "
       << startTime << " " << execTime << " " << newProcess.getFinishTime() 
       << endl;
}

/*******************************************************************************
 * Function to check if priority queue is empty
 * Author: Andrew Shore
 * Date Last Modified: 23 March 2010
 *
 * Simply calls the STL priority queue function empty() to check if the 
 * priority queue is empty.
 *
 * Parameters: none
 *
 * Output: none
 *
 * Returns: True if schedule is empty, false otherwise
*******************************************************************************/
bool Scheduler::empty(){
  return theSchedule.empty();
}

/*******************************************************************************
 * Function to 'pop' off(remove) top element in the priority queue.
 * Author: Andrew Shore
 * Date Last Modified: 23 March 2010
 *
 * Functions pops off the top element of the queue(the element with the smallest
 * finish time) provided the priority queue is non-empty.
 *
 * Parameters: none
 * 
 * Output: none
 *
 * Returns: none
*******************************************************************************/
void Scheduler::pop(){
  if( !theSchedule.empty() ){
    theSchedule.pop();
  }
  

  
}

/*******************************************************************************
 * Function to look at the top process of the queue but not remove it
 * Author: Andrew Shore
 * Date Last Modified: 23 March 2010
 *
 * If the priority queue is non-empty it returns the top process, otherwise 
 * it returns an unitialized proccess.
 *
 * Parameters: none
 *
 * Output: none
 *
 * Returns: A process with the smallest finish time
*******************************************************************************/
Process Scheduler::top(){
  Process temp;
  if( theSchedule.empty() ){
    return temp;
  }else{
    return theSchedule.top();
  }
}
/*******************************************************************************
 * Function to 'dump' priority queue and assign it to a string.
 * Author: Andrew Shore
 * Date Last Modified: 23 March 2010
 *
 * First the function copies the priority queue to a temporary queue then 
 * procceds to add the string equivalent of the top process to a temporary
 * string than pop it off until the queue is empty. Uses the toString method
 * of the Process class to convert the top process into a string.
 *
 * Parameters: none
 *
 * Output: none
 *
 * Returns: A string version of the priority queue
*******************************************************************************/
string Scheduler::toStringDump(){
  cout << TAG << " enter toStringDump\n";

  string s;
  Process temp;
  priority_queue<Process, vector<Process>, Comparison> tempPQ = theSchedule;  

  cout << TAG << " process queue\n";
  while( !tempPQ.empty() ){
    temp = tempPQ.top();
    s += temp.toString() + "\n";
    tempPQ.pop();
  }
  
  s += Utils::Format(TAG);
  s += " leaving toStringDump\n";
  return s;  
}
